<template>
    <view class="uni-indexed-list" ref="list" id="list">
        <scroll-view :scroll-into-view="scrollViewId" class="uni-indexed-list__scroll" scroll-y>
            <view v-for="(list, idx) in lists" :key="idx" :id="'uni-indexed-list-' + idx">
                <m-indexed-list-item
                    :list="list"
                    :loaded="loaded"
                    :idx="idx"
                    :showSelect="showSelect"
                    @itemClick="onClick"
                ></m-indexed-list-item>
            </view>
        </scroll-view>
        <view
            class="uni-indexed-list__menu"
            @touchstart="touchStart"
            @touchmove.stop.prevent="touchMove"
            @touchend="touchEnd"
            @mousedown.stop="mousedown"
            @mousemove.stop.prevent="mousemove"
            @mouseleave.stop="mouseleave"
        >
            <view
                v-for="(list, key) in lists"
                :key="key"
                class="uni-indexed-list__menu-item"
                :class="touchmoveIndex == key ? 'uni-indexed-list__menu--active' : ''"
            >
                <text
                    class="uni-indexed-list__menu-text"
                    :class="touchmoveIndex == key ? 'uni-indexed-list__menu-text--active' : ''"
                >
                    {{ list.key }}
                </text>
            </view>
        </view>
        <view v-if="touchmove" class="uni-indexed-list__alert-wrapper">
            <text class="uni-indexed-list__alert">{{ lists[touchmoveIndex].key }}</text>
        </view>
    </view>
</template>
<script lang="ts">
/**
 * IndexedList 索引列表
 * @description 用于展示索引列表
 * @tutorial https://ext.dcloud.net.cn/plugin?id=375
 * @property {Boolean} showSelect = [true|false] 展示模式
 * 	@value true 展示模式
 * 	@value false 选择模式
 * @property {Object} options 索引列表需要的数据对象
 * @event {Function} click 点击列表事件 ，返回当前选择项的事件对象
 * @example <uni-indexed-list options="" showSelect="false" @click=""></uni-indexed-list>
 */
import { defineComponent } from 'vue'
import MIndexedListItem from './MIndexedListItem.vue'
export default defineComponent({
    name: 'UniIndexedList',
    emits: ['click'],
    components: {
        MIndexedListItem
    },
    props: {
        options: {
            type: Array,
            default() {
                return []
            }
        },
        showSelect: {
            type: Boolean,
            default: false
        },
        top: {
            type: Number,
            default: 0
        }
    },
    data() {
        return {
            lists: new Array<any>(),
            winHeight: 0,
            itemHeight: 0,
            winOffsetY: 0,
            touchmove: false,
            touchmoveIndex: -1,
            scrollViewId: '',
            touchmovable: true,
            loaded: false,
            isPC: false
        }
    },
    watch: {
        options: {
            handler: function () {
                this.setList()
            },
            deep: true
        }
    },
    mounted() {
        // #ifdef H5
        this.isPC = this.IsPC()
        // #endif
        setTimeout(() => {
            this.setList()
        }, 50)
        setTimeout(() => {
            this.loaded = true
        }, 300)
    },
    methods: {
        setList() {
            let index = 0
            this.lists = []
            this.options.forEach((value: any) => {
                if (value.data.length === 0) {
                    return
                }
                let indexBefore = index
                let items = value.data.map((item: any) => {
                    let obj: any = {}
                    obj['key'] = value.letter
                    obj['name'] = item
                    obj['itemIndex'] = index
                    index++
                    obj.checked = item.checked ? item.checked : false
                    return obj
                })
                this.lists.push({
                    title: value.letter,
                    key: value.letter,
                    items: items,
                    itemIndex: indexBefore
                })
            })
            // #ifndef APP-NVUE
            uni.createSelectorQuery()
                .in(this)
                .select('#list')
                .boundingClientRect()
                .exec((ret) => {
                    this.winOffsetY = ret[0].top
                    this.winHeight = ret[0].height
                    this.itemHeight = (this.winHeight - 100) / this.lists.length
                })
            // #endif
        },
        touchStart(e: any) {
            this.touchmove = true
            let pageY = this.isPC ? e.pageY : e.touches[0].pageY
            let index = Math.floor((pageY - this.winOffsetY) / this.itemHeight)
            let item = this.lists[index]
            if (item) {
                this.scrollViewId = 'uni-indexed-list-' + index
                this.touchmoveIndex = index
            }
        },
        touchMove(e: any) {
            // #ifndef APP-PLUS
            let pageY = this.isPC ? e.pageY : e.touches[0].pageY
            let index = Math.floor((pageY - this.winOffsetY) / this.itemHeight)
            if (this.touchmoveIndex === index) {
                return false
            }
            let item = this.lists[index]
            if (item) {
                this.scrollViewId = 'uni-indexed-list-' + index
                this.touchmoveIndex = index
            }
            // #endif
        },
        touchEnd(e: any) {
            this.touchmove = false
            // this.touchmoveIndex = -1
        },

        /**
         * 兼容 PC @tian
         */

        mousedown(e: any) {
            if (!this.isPC) return
            this.touchStart(e)
        },
        mousemove(e: any) {
            if (!this.isPC) return
            this.touchMove(e)
        },
        mouseleave(e: any) {
            if (!this.isPC) return
            this.touchEnd(e)
        },

        // #ifdef H5
        IsPC() {
            var userAgentInfo = navigator.userAgent
            var Agents = ['Android', 'iPhone', 'SymbianOS', 'Windows Phone', 'iPad', 'iPod']
            var flag = true
            for (let v = 0; v < Agents.length - 1; v++) {
                if (userAgentInfo.indexOf(Agents[v]) > 0) {
                    flag = false
                    break
                }
            }
            return flag
        },
        // #endif

        onClick(e: any) {
            let { idx, index } = e
            let obj: any = {}
            for (let key in this.lists[idx].items[index]) {
                obj[key] = this.lists[idx].items[index][key]
            }
            let select: any = []
            if (this.showSelect) {
                this.lists[idx].items[index].checked = !this.lists[idx].items[index].checked
                this.lists.forEach((value, idx) => {
                    value.items.forEach((item: any, index: any) => {
                        if (item.checked) {
                            let obj: any = {}
                            for (let key in this.lists[idx].items[index]) {
                                obj[key] = this.lists[idx].items[index][key]
                            }
                            select.push(obj)
                        }
                    })
                })
            }
            this.$emit('click', {
                item: obj,
                select: select
            })
        }
    }
})
</script>
<style lang="scss">
.uni-indexed-list {
    position: absolute;
    left: 0;
    top: calc(v-bind(top) * 2rpx);
    right: 0;
    bottom: 0;
    /* #ifndef APP-NVUE */
    display: flex;
    /* #endif */
    flex-direction: row;
}

.uni-indexed-list__scroll {
    flex: 1;
}

.uni-indexed-list__menu {
    width: 48rpx;
    /* #ifndef APP-NVUE */
    display: flex;
    /* #endif */
    flex-direction: column;
    background-color: white;
    padding-bottom: 200rpx;
}

.uni-indexed-list__menu-item {
    /* #ifndef APP-NVUE */
    display: flex;
    /* #endif */
    flex: 1;
    align-items: center;
    justify-content: center;
    /* #ifdef H5 */
    cursor: pointer;
    /* #endif */
}

.uni-indexed-list__menu-text {
    font-size: 24rpx;
    text-align: center;
    color: #aaa;
}

.uni-indexed-list__menu--active {
    // background-color: rgb(200, 200, 200);
}

.uni-indexed-list__menu--active {
}

.uni-indexed-list__menu-text--active {
    border-radius: 32rpx;
    width: 32rpx;
    height: 32rpx;
    line-height: 32rpx;
    background-color: $uni-color-error;
    color: #fff;
}

.uni-indexed-list__alert-wrapper {
    position: absolute;
    left: 0;
    top: 0;
    right: 0;
    bottom: 0;
    /* #ifndef APP-NVUE */
    display: flex;
    /* #endif */
    flex-direction: row;
    align-items: center;
    justify-content: center;
}

.uni-indexed-list__alert {
    width: 160rpx;
    height: 160rpx;
    border-radius: 160rpx;
    text-align: center;
    line-height: 160rpx;
    font-size: 70rpx;
    color: #fff;
    background-color: rgba(0, 0, 0, 0.5);
}
</style>
